package com.cyh.ebpttoolswar.commmon;

import cn.hutool.core.util.StrUtil;
import com.cyh.ebpttoolswar.entitys.Column;
import com.cyh.ebpttoolswar.entitys.Config;
import com.cyh.ebpttoolswar.entitys.Table;
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class EntityGenerator {

  /** 数据库驱动 */
  public static final String DBDRIVER = "com.mysql.cj.jdbc.Driver";
  // 模板包名
  public static String TEMPLATE_PATH = "/templates/";

  public void generator(Config config, String DBURL, String DBUSER, String DBPASS)
      throws ClassNotFoundException, SQLException {
    // 1、使用CLASS 类加载驱动程序 这玩意大家很熟悉吧 最早的无框架jdbc搞法
    Class.forName(DBDRIVER);
    // 2、连接数据库
    Connection con = DriverManager.getConnection(DBURL, DBUSER, DBPASS);
    if (con == null) {
      return;
    }
    // 获取表
    List<Table> tables = DbHelper.getTableList(config, con);
    String tableName = config.getTableName();
    for (Table table : tables) {
      if (!StrUtil.isEmpty(tableName)
          && !tableName
              .toLowerCase(Locale.ROOT)
              .equals(table.getTableName().toLowerCase(Locale.ROOT))) {
        continue;
      }
      table.setDefault(config);
      // 获取列
      table.setColumns(DbHelper.getTableColumns(table.getTableName(), config, con));
      // 检查要引入的包，如果java.lang.*则不用引入
      List<Column> columnList = table.getColumns();
      table.setPrimaryKeyIsNotEmpty(0);
      for ( Column column: columnList) {
          if(1 == (column.getPrimary())){
            table.setPrimaryKeyIsNotEmpty(1);
            break;
          }
      }
      // 开始生成
      System.out.println("==========Entity生成==========");
      write(
          table,
          config,
          config.getEntityTemPateName(),
          table.getPackageName(),
          "/entity",
          table.getEntityNameWithEntity() + ".java");

      System.out.println("==========Dao生成==========");
      write(
          table,
          config,
          config.getDaoTemPateName(),
          table.getPackageName(),
          "/dao",
          table.getDaoName() + ".java");

      System.out.println("==========Mapper生成==========");
      write(
          table,
          config,
          config.getMapperTemPateName(),
          table.getPackageName(),
          "/dao",
          table.getMapperName() + ".xml");

      System.out.println("==========Controller生成==========");
      write(
          table,
          config,
          config.getControllerTemPateName(),
          table.getPackageName(),
          "/controller",
          table.getControllerName() + ".java");

      //      // 暂时不生成Service
      //      System.out.println("==========Service生成==========");
      //      write(
      //              table,
      //              config,
      //              config.getServiceTemPateName(),
      //              table.getPackageName(),
      //              "/service",
      //              table.getServiceName() + ".java");

      //      System.out.println("==========Form生成==========");
      //      write(
      //          table,
      //          config,
      //          config.getFormTemPateName(),
      //          table.getPackageName(),
      //          "",
      //          table.getFormName() + ".java");

      //      System.out.println("==========Action生成==========");
      //      write(
      //          table,
      //          config,
      //          config.getActionTemPateName(),
      //          table.getPackageName(),
      //          "",
      //          table.getActionName() + ".java");

      // 页面生成 type 0:springboot 1:springmvc
      //            String viewDir="/"+config.getDefaultPackageName().replace(".", "_");
      //            viewDir = viewDir.substring(0,viewDir.length());
      //            String
      // pageDir=viewDir+"/"+table.getPagePackageName()+"/"+table.getEntityFirstLowerName();
      //            System.out.println("==========Api生成==========");
      //
      // write(table,config,config.getApiTemPateName(),table.getApiPackageName(),table.getApiName()+".java");
      //            System.out.println("==========ApiUser生成==========");
      //
      // write(table,config,config.getApiUserTemPateName(),table.getApiUserPackageName(),table.getApiUserName()+".java");
      //            System.out.println("==========Page index.ftl生成==========");
      //            write(table,config,config.getIndexTemPateName(),pageDir,"index.html");
      //            System.out.println("==========Page build.ftl生成==========");
      //            write(table,config,config.getBuildTemPateName(),pageDir,"build.html");
      //            System.out.println("==========Page edit.ftl生成==========");
      //            write(table,config,config.getEditTemPateName(),pageDir,"edit.html");
      //            System.out.println("==========Page show.ftl生成==========");
      //            write(table,config,config.getShowTemPateName(),pageDir,"show.html");
      //            System.out.println("==========Page form.ftl生成==========");
      //            write(table,config,config.getPformTemPateName(),pageDir,"form.html");
    }
  }

  /**
   * 写出代码文件
   *
   * @param table
   * @param config
   * @param ftl
   * @param packageName
   * @param fileName
   */
  private void write(
      Table table, Config config, String ftl, String packageName, String dir, String fileName) {
    if (StringUtils.isNotEmpty(table.getTableName())) {
      String entityFolder = config.getSrcPath() + "/" + packageName + dir;
      String entityFile = entityFolder + "/" + fileName;
      File file = new File(entityFolder);
      if (!file.exists()) {
        file.mkdirs();
      }
      System.out.println("生成：" + entityFile);
      Map<String, Object> root = new HashMap<>();
      root.put("config", config);
      root.put("table", table);
      root.put("columns", table.getColumns());
      root.put("primaryColumns", table.getPrimaryColumn());
      try {
        // freemarker写出
        loadContentByTemplate(config, root, ftl, entityFile);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * freemarker模板写出
   *
   * @param config
   * @param root
   * @param TemplateName
   * @param targetFile
   * @throws Exception
   */
  @SuppressWarnings("deprecation")
  private void loadContentByTemplate(Config config, Map<String, Object> root, String TemplateName, String targetFile) throws Exception {

    InputStream is = null;
    BufferedReader br = null;
    Writer out = null;
    try {
      // 加载freemarker模板文件
      String path = TEMPLATE_PATH + TemplateName;

      is = this.getClass().getResourceAsStream(path);

      br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
      Template template = new Template(TemplateName, br);
      // 如果模板文件放在jar包外面 则用路劲写出
      //			Template template = cfg.getTemplate(TemplateName);
      // 输出模板
      out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "UTF-8"));
      template.process(root, out);
      out.flush();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      out.close();
      br.close();
      is.close();
    }
  }
}
